#include "ImageProcesser.h"
#include "Controller.h"
#include "mainwindow.h"
QImage* Controller::Img;
ImageProcesser::ImageProcesser(QObject *parent) : QObject(parent)
{
    //Retrieve Signals from Controller
    Controller *ctrl = new Controller(this);
    connect(ctrl, SIGNAL(sendImg(QImage *)), this, SLOT(recImg(QImage *)));
    connect(ctrl, SIGNAL(sendError(QString)), this, SLOT(recError(QString)));
    connect(ctrl, SIGNAL(sendPath(QString)), this, SLOT(recPath(QString)));
    //Distribute Multiple Signals from SignalMapper
    connect(MainWindow::signalMapper, SIGNAL(mapped(const QString &)),
            this, SLOT(imgtypeChange(const QString &)));
    connect(MainWindow::signalMapper, SIGNAL(mapped(const QString &)),
            this, SLOT(inverseColor(const QString &)));
    connect(MainWindow::signalMapper, SIGNAL(mapped(const QString &)),
            this, SLOT(redo(const QString &)));
    connect(MainWindow::signalMapper, SIGNAL(mapped(const QString &)),
            this, SLOT(undo(const QString &)));
}
void ImageProcesser::recImg(QImage *img)
{
    imgs.push_back(img);
    //Send Signal to MainWindow
    emit sendImg(imgs.last());
}
void ImageProcesser::recPath(QString str)
{
    paths.push_back(str);
    emit sendPath(paths.last());
}
void ImageProcesser::imgtypeChange(const QString &str)
{
    if (str == "RGB" && !imgs.isEmpty())
    {
        Controller::Img=imgs.last();
        emit sendImg(imgs.last());
    }
    else if (str == "GRAY" && !imgs.isEmpty())
    {
        QImage *imgGray = new QImage;
        *imgGray = imgs.last()->convertToFormat(QImage::Format_Grayscale8, Qt::AutoColor);
        Controller::Img=imgGray;
        emit sendImg(imgGray);
    }
    else if (str == "BINARY" && !imgs.isEmpty())
    {
        QImage *imgBin = new QImage;
        *imgBin = imgs.last()->convertToFormat(QImage::Format_Mono, Qt::AutoColor);
        Controller::Img=imgBin;
        emit sendImg(imgBin);
    }
}
void ImageProcesser::inverseColor(const QString &str)
{
    if (str == "INVERSE"&& !imgs.isEmpty() )
    {
        QImage *imgInv = new QImage;
        *imgInv = *imgs.last();
        imgInv->invertPixels(QImage::InvertRgb);
        imgs.push_back(imgInv); //backup for undo
        if(!paths.isEmpty())
        paths.push_back(paths.last());
        Controller::Img=imgInv;
        emit sendImg(imgInv);
    }
}
void ImageProcesser::undo(const QString &str)
{
    if (str == "UNDO" && imgs.length() > 1 )
    {
        imgsHold.push_back(imgs.last());
        imgs.pop_back();
        pathsHold.push_back(paths.last());
        paths.pop_back();
        emit sendPath(paths.last());
        Controller::Img=imgs.last();//for save
        emit sendImg(imgs.last());
        emit sendACK(true);// to RGB
    }
    else
        emit sendACK(false);
}
void ImageProcesser::redo(const QString &str)
{
    if (str == "REDO" && !imgsHold.isEmpty())
    {
        imgs.push_back(imgsHold.last());      
        imgsHold.pop_back();
        paths.push_back(pathsHold.last());
        pathsHold.pop_back();
        emit sendPath(paths.last());
        Controller::Img=imgs.last();//for save
        emit sendImg(imgs.last());
        emit sendACK(true);// to RGB
    }
    else
        emit sendACK(false);
}

void ImageProcesser::recError(QString str)
{
    emit sendError(str);
}
